package com.tingyuge.thinking.spring.configuration.bean.scope;


import com.tingyuge.thinking.spring.ioc.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

/**
 * ThreadLocal 级别的scope
 *
 * @author xiaodao
 * @version 1.0
 * @date 2021/7/10
 */
public class ThreadLocalScopeDemo {

    @Bean
    @Scope(ThreadLocalScope.scope_name)
    public User user() {
        User user = new User();
        user.setId(System.nanoTime());
        return user;
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册 configuration class（配置类）--->也是 spring bean
        applicationContext.register(ThreadLocalScopeDemo.class);
        //启动应用上下文
        applicationContext.addBeanFactoryPostProcessor(beanFactory -> {
            beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
                @Override
                public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                    //注册自定义的scope
                    beanFactory.registerScope(ThreadLocalScope.scope_name, new ThreadLocalScope());
                    return bean;
                }
            });
        });

        applicationContext.refresh();
        //依赖查找  AnnotationDependencyFieldInjectionDemo
        ThreadLocalScopeDemo demo = applicationContext.getBean(ThreadLocalScopeDemo.class);

        scopeBeanByLookup(applicationContext);

        //显示关闭应用上下文
        applicationContext.close();
    }

    private static void scopeBeanByLookup(AnnotationConfigApplicationContext applicationContext) {
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        System.out.println(beanDefinitionNames.length);
        for (int i = 0; i <3; i++) {
            //singleton每次都是一样的
            Thread user = new Thread(() -> {
                User theadLocalUser = applicationContext.getBean("user", User.class);
                System.out.println("singletonUser: " + theadLocalUser);
            });
            user.start();
            try {
                user.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
        System.out.println(beanDefinitionNames.length);

    }

}
